package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * ClassName: ReportServiceImpl
 * Package:
 * Description
 * 数据统计相关接口
 *
 * @Author xw
 * @Create 2023/11/29 11:55
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    /*
     * 订单持久层 接口
     * */
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 营业额数据统计
     */
    @Override
    public TurnoverReportVO getTurnover(LocalDate begin, LocalDate end) {

        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);

        // 将每一天加入到集合中，组成x轴日期数据
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);//日期计算，获得指定日期后1天的日期
            dateList.add(begin);
        }

        // 接下来根据日期数据，获得对应的y轴数据
        List<Double> turnoverList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            Map map = new HashMap();

            // 状态已完成
            map.put("status", Orders.COMPLETED);
            map.put("begin", beginTime);
            map.put("end", endTime);
            log.info("状态已完成：{}", map);

            // 根据动态条件统计营业额
            Double turnover = orderMapper.sumByMap(map);

            // 如果查询的数据是null，则设置0.0
            turnover = turnover == null ? 0.0 : turnover;

            // 添加进入集合中，组成y轴数据
            turnoverList.add(turnover);
        }

        //数据封装：根据接口文档要求，使用逗号，隔开
        return TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .turnoverList(StringUtils.join(turnoverList, ","))
                .build();
    }


    /**
     * 用户数据统计
     */
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {

        // x 轴
        List<LocalDate> list = new ArrayList<>();
        list.add(begin);

        // 将每一天加入到集合中，组成x轴日期数据
        while (!begin.equals(end)) {
            begin = begin.plusDays(1); //日期计算，获得指定日期后1天的日期
            list.add(begin);
        }

        // y 轴
        List<Integer> objectsY1 = new ArrayList<>(); // 新增
        List<Integer> objectsY2 = new ArrayList<>(); // 用户总量

        for (LocalDate localDate : list) {


            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            log.info("beginTime：{}", beginTime);
            log.info("endTime：{}", endTime);

            // 拼接出 y1 轴
            // select count(id) from user where create_time > ? and create_time < ?
            Integer y1 = orderMapper.userStatistics(beginTime, endTime);

            // 拼接出 y2 轴
            // select count(*) from user where create_time<= endTime
            Integer y2 = orderMapper.userStatistics(null, endTime);


            objectsY1.add(y1);
            objectsY2.add(y2);


        }


        log.info("用户数据统计：{}", list);


        return UserReportVO.builder()
                .dateList(StringUtils.join(list, ","))
                .newUserList(StringUtils.join(objectsY1, ","))
                .totalUserList(StringUtils.join(objectsY2, ","))
                .build();
    }


    /**
     * 订单统计接口
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {

        // x 轴
        List<LocalDate> listX = new ArrayList<>();
        listX.add(begin);

        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            listX.add(begin);

        }

        // y 轴
        List<Integer> objectsY1 = new ArrayList<>(); // 订单总数
        List<Integer> objectsY2 = new ArrayList<>(); // 有效订单数

        // 拼接 y1和y2轴
        for (LocalDate x : listX) {
            LocalDateTime beginTime = LocalDateTime.of(x, LocalTime.MIN);
            LocalDateTime entTime = LocalDateTime.of(x, LocalTime.MAX);


            // select * from orders where order_time >= beginTime and order_time <= entTime
            Integer Y1 = orderMapper.ordersStatistics(beginTime, entTime, null); // 订单总数

            // select * from orders where order_time >= beginTime and order_time <= entTime and status = 5
            Integer Y2 = orderMapper.ordersStatistics(beginTime, entTime, 5); // 有效订单数

            // 添加数据
            objectsY1.add(Y1);
            objectsY2.add(Y2);
        }
        // 时间区间内的总订单数
        Integer totalOrderCount = objectsY1.stream().reduce(Integer::sum).get();
        // 时间区间内的总有效订单数
        Integer validOrderCountList = objectsY2.stream().reduce(Integer::sum).get();

        // 订单完成率
        Double orderCompletionRate = 0.0;
        if (totalOrderCount != 0) {
            orderCompletionRate = validOrderCountList.doubleValue() / totalOrderCount;
        }


        return OrderReportVO.builder()
                .dateList(StringUtils.join(listX, ","))

                .orderCountList(StringUtils.join(objectsY1, ","))
                .validOrderCountList(StringUtils.join(objectsY2, ","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCountList)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }


    /**
     * 查询销量排名top10接口
     */
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        // 开始时间
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        // 结束时间
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        // 商品数据
        List<GoodsSalesDTO> list = orderMapper.top10(beginTime, endTime);


        String nameList = StringUtils.join(list.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()), ",");
        String numberList = StringUtils.join(list.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()), ",");

        return SalesTop10ReportVO.builder()
                .nameList(nameList)
                .numberList(numberList)
                .build();
    }


    @Autowired
    private WorkspaceServiceImpl workspaceService;

    /**
     * 导出运营数据报表
     */
    @Override
    public void export(HttpServletResponse response) throws IOException {

        //  过去 30 天
        LocalDate dataBeginDataTime = LocalDate.now().minusDays(30);
        // 昨天
        LocalDate dataEndDataTime = LocalDate.now().minusDays(1);

        //查询概览数据
        BusinessDataVO businessData = workspaceService.getBusinessData(
                LocalDateTime.of(dataBeginDataTime, LocalTime.MIN),
                LocalDateTime.of(dataEndDataTime, LocalTime.MAX)
        );


        //2. 通过POI将数据写入到Excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("运营数据报表模板.xlsx");


        //基于模板文件创建一个新的Excel文件
        XSSFWorkbook excel = new XSSFWorkbook(in);

        // 页
        XSSFSheet sheet = excel.getSheetAt(0);

        // 行
        XSSFRow row = sheet.createRow(1);
        // 单元格
        row.createCell(0).setCellValue("时间：" + dataBeginDataTime + "至" + dataEndDataTime);


        //获得第4行
        XSSFRow row4 = sheet.getRow(3);
        row4.getCell(1).setCellValue(businessData.getTurnover()); // 营业额
        row4.getCell(3).setCellValue(businessData.getOrderCompletionRate()); // 订单完成率
        row4.getCell(5).setCellValue(businessData.getNewUsers()); // 新增用户数


        //获得第5行
        XSSFRow row5 = sheet.getRow(4);
        row5.getCell(1).setCellValue(businessData.getValidOrderCount()); // 营业额
        row5.getCell(3).setCellValue(businessData.getUnitPrice()); // 订单完成率


        // for 30天前 ~ 昨天的数据
        for (int i = 0; i < 30; i++) {
            // 降序，假设 11/30日 ~ 10/01日，就是 11/30、11/29
            LocalDate localDate = dataEndDataTime.minusDays(i);


            BusinessDataVO Data = workspaceService.getBusinessData(
                    LocalDateTime.of(localDate, LocalTime.MIN),
                    LocalDateTime.of(localDate, LocalTime.MAX)
            );


            XSSFRow rowI = sheet.getRow(7 + i);
            rowI.getCell(0).setCellValue(localDate.toString());
            rowI.getCell(1).setCellValue(Data.getTurnover());
            rowI.getCell(2).setCellValue(Data.getValidOrderCount());
            rowI.getCell(3).setCellValue(Data.getOrderCompletionRate());
            rowI.getCell(4).setCellValue(Data.getUnitPrice());
            rowI.getCell(5).setCellValue(Data.getNewUsers());


        }


        // 通过输出流将Excel文件下载到客户端浏览器
        ServletOutputStream out = response.getOutputStream();
        excel.write(out);


        // 关流
        out.close();
        excel.close();


    }


}
